package com.key.win.common.websocket.utils;

import com.alibaba.fastjson.JSON;
import com.key.win.base.auth.AuthenticationUtil;
import com.key.win.base.auth.detail.Authentication;
import com.key.win.base.util.JsonUtils;
import com.key.win.common.websocket.manager.WebSocketManager;
import com.key.win.common.websocket.vo.WebsocketBaseMessage;
import com.key.win.system.model.SysDevice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Component
public class BroadcastMessageUtil {
    private static final Logger logger = LoggerFactory.getLogger(BroadcastMessageUtil.class);

    public static final String WEBSCOKET_BASE_MESSAGE = "WebScoketBaseMessage";

    private static TaskExecutor taskExecutor;

    private static WebSocketManager webSocketManager;

    @Autowired
    public  void setWebSocketManager(WebSocketManager webSocketManager) {
        BroadcastMessageUtil.webSocketManager = webSocketManager;
    }

    @Autowired
    public void setTaskExecutor(TaskExecutor taskExecutor) {
        BroadcastMessageUtil.taskExecutor = taskExecutor;
    }

    public static void broadcast(String action, String mapper, Object message) {
        WebsocketBaseMessage websocketBaseMessage = new WebsocketBaseMessage();
        websocketBaseMessage.setAction(action);
        websocketBaseMessage.setMapper(mapper);
        websocketBaseMessage.setMessage(JsonUtils.toJsonNoException(message));
        webSocketManager.broadcast(websocketBaseMessage);
    }


    public static void broadcastDeviceStatus(SysDevice sysDevice) {
        SysDevice broadcastDevice = new SysDevice();
        broadcastDevice.setOnLine(sysDevice.isOnLine());
        broadcastDevice.setCode(sysDevice.getCode());
        broadcastDevice.setToken(sysDevice.getToken());
        broadcastDevice.setName(sysDevice.getName());
        Map map = JSON.parseObject(JSON.toJSONString(broadcastDevice), Map.class);
        map.put("message","人员设备上下线提示");
        BroadcastMessageUtil.broadcast("WebScoketDeviceStatusAction", WEBSCOKET_BASE_MESSAGE, map);
    }

    public static void asyncbroadcastDeviceStatus(SysDevice sysDevice) {
        CompletableFuture.runAsync(() -> {
            try {
                logger.info("设备[{}]开始广播", sysDevice.getCode());
                if (sysDevice != null) {
                    BroadcastMessageUtil.broadcastDeviceStatus(sysDevice);
                }
                logger.info("设备[{}]结束广播", sysDevice.getCode());
            } catch (Exception e) {
                logger.error("设备[{}]广播失败：{}", sysDevice.getCode(), e.getMessage(),e);
            }

        }, taskExecutor);
    }

    public static void broadcastUserStatus(Authentication loginUser) {
        Authentication broadcastLoginUser = new Authentication();
        broadcastLoginUser.setNickName(loginUser.getNickName());
        broadcastLoginUser.setUserName(loginUser.getUserName());
        broadcastLoginUser.setOnLine(loginUser.isOnLine());
        broadcastLoginUser.setToken(loginUser.getToken());
        AuthenticationUtil.setCurrentUser(loginUser);
        Map map = JSON.parseObject(JSON.toJSONString(broadcastLoginUser), Map.class);
        map.put("message","人员设备上下线提示");
        BroadcastMessageUtil.broadcast("WebScoketLoginStatusAction", WEBSCOKET_BASE_MESSAGE, map);
    }

    public static void asyncBroadcastUserStatus(Authentication loginUser) {
        CompletableFuture.runAsync(() -> {
            try {
                logger.info("用户[{}]开始广播", loginUser.getUserName());
                if (loginUser != null) {
                    BroadcastMessageUtil.broadcastUserStatus(loginUser);
                }
                logger.info("用户[{}]结束广播", loginUser.getUserName());
            } catch (Exception e) {
                logger.error("用户[{}]广播失败：{}", loginUser.getUserName(), e.getMessage(),e);
            }

        }, taskExecutor);
    }
}
